<?php
	class PDODB implements I_DAO
	{
		private $host;  // 主机地址
        private $port;  // 端口号
        private $user;  // 用户名
        private $pwd;  // 密码
        private $charset;// 字符集
        private $dbname;    // 数据库名
        private $dsn;
        private $pdo;
        private static $instance;// 用于保存对象

        /**
         * 构造方法
         * @param array $arr 关联数组
         */
        private function __construct($arr)
        {	
        	//初始化属性
        	$this->initParams($arr);
        	//初始化DSN
        	$this-> initDSN();
        	//实例化Pdo对象
        	$this->initPDO();
        	//初始化PDO属性
        	$this->initAttribute();
        }
        /**
         * 获得单例对象
         * @param  array $arr 传递给构造方法的数组参数
         */
        public static function getInstance($arr) 
        {
            if(!self::$instance instanceof self) 
            {
                self::$instance = new self($arr);
            }
            return self::$instance;   
        }
        /**
         * 初始化属性
         */
        private function initParams($arr)
        {
        	$this->host=isset($arr['host'])?$arr['host']:'localhost';
            $this->port=isset($arr['port'])?$arr['port']:'3306';
            $this->user=isset($arr['user'])?$arr['user']:'root';
            $this->pwd=isset($arr['pwd'])?$arr['pwd']:'zhuhailingji';
            $this->charset = isset($arr['charset']) ? $arr['charset']:'utf8';
            $this->dbname = isset($arr['dbname']) ? $arr['dbname']:'php24';
        }
        /**
         * 初始化DSN
         */
        private function initDSN()
        {
        	$this->dsn="mysql:host=$this->host;port=$this->port;dbname=$this->dbname;charset=$this->charset";
        }
        /**
         * 初始化PDO,得到一个PDO对象
         */
        private  function initPDO()
        {
        	try
        	{
        		$this->pdo = new PDO($this->dsn,$this->user,$this->pwd);
        	}
        	catch(PDOException $e)
        	{
        		echo '数据库连接失败!<br />';
        		echo '错误的编号为:',$e->getCode(),'<br />';
        		echo '错误的信息为:',$e->getMessage(),'<br />';
        		echo '错误的文件为:',$e->getFile(),'<br />';
        		echo '错误的行号为:',$e->getLine(),'<br />';
        		die;
        	}
        }
        /**
         * 初始化PDO对象,开启异常模式
         */
        private function initAttribute()
        {
        	$this->pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
        }
        /**
         *输出异常信息
         */
        private function my_error($e)
        {
    		echo 'SQL语句执行失败!<br />';
    		echo '错误的编号为:',$e->getCode(),'<br />';
    		echo '错误的信息为:',$e->getMessage(),'<br />';
    		echo '错误的文件为:',$e->getFile(),'<br />';
    		echo '错误的行号为:',$e->getLine(),'<br />';
    		die;
        } 
        /**
         * 实现增删改
         */
        public function my_query($sql)
        {
        	try
        	{
        		$result =$this->pdo->exec($sql);
        	}
        	catch(PDOException $e)
        	{
        		$this->my_error($e);
        	}
        	return $result;
        }
        /**
         *查询所有结果fetchAll
         */
        public function fetchAll($sql)
        {
        	try
        	{
        		$stmt=$this->pdo->query($sql);
        		$result =$stmt->fetchAll(PDO::FETCH_ASSOC);
        		$stmt->closeCursor();
        	}
        	catch(PDOException $e)
        	{
        		$this->my_error($e);
        	}
        	return $result;
        }
        /**
         * 查询单行数据
         */
         public function fetchRow($sql)
        {
        	try
        	{
        		$stmt=$this->pdo->query($sql);
        		$result =$stmt->fetch(PDO::FETCH_ASSOC);
        		$stmt->closeCursor();
        	}
        	catch(PDOException $e)
        	{
        		$this->my_error($e);
        	}
        	return $result;
        }
           /**
         * 查询单列数据
         */
         public function fetchColumn($sql,$i=NULL)
        {
        	try
        	{
        		$stmt=$this->pdo->query($sql);
        		if (is_null($i))
        		{
        			$result =$stmt->fetchColumn();
        		}
        		else
        		{
        			$result =$stmt->fetchColumn($i);
        		}	
        		$stmt->closeCursor();
        	}
        	catch(PDOException $e)
        	{
        		$this->my_error($e);
        	}
        	return $result;
        }
        /**
         * 私有化__clone
         */
        private function __clone()
        {

        }
	}